<script setup lang="ts">
import type { InputInstance } from "element-plus";
import { ElButton, ElInput } from "element-plus";
import { ref, watch } from "vue";

defineProps<{ msg: string }>();

const display = ref("0");
const currentOperator = ref<string | null>(null);
const firstOperand = ref<number | null>(null);
const waitingForOperand = ref(false);

// 定义按钮列表
const buttons = [
  { label: "AC", value: "AC", type: "primary", span: 1 },
  { label: "±", value: "+/-", type: "primary", span: 1 },
  { label: "%", value: "%", type: "primary", span: 1 },
  { label: "÷", value: "/", type: "primary", span: 1 },
  { label: "7", value: "7", type: "default", span: 1 },
  { label: "8", value: "8", type: "default", span: 1 },
  { label: "9", value: "9", type: "default", span: 1 },
  { label: "×", value: "*", type: "primary", span: 1 },
  { label: "4", value: "4", type: "default", span: 1 },
  { label: "5", value: "5", type: "default", span: 1 },
  { label: "6", value: "6", type: "default", span: 1 },
  { label: "-", value: "-", type: "primary", span: 1 },
  { label: "1", value: "1", type: "default", span: 1 },
  { label: "2", value: "2", type: "default", span: 1 },
  { label: "3", value: "3", type: "default", span: 1 },
  { label: "+", value: "+", type: "primary", span: 1 },
  { label: "0", value: "0", type: "default", span: 2 },
  { label: ".", value: ".", type: "default", span: 1 },
  { label: "=", value: "=", type: "primary", span: 1 },
];

// 输入框引用
const inputRef = ref<InputInstance>();

function inputDisplay(value: string) {
  // 移除所有非数字和小数点的字符（除了负号）
  const cleanValue = value.replace(/[^0-9.-]/g, "");

  if (cleanValue === "" || cleanValue === "-") {
    display.value = cleanValue || "0";
    return;
  }

  display.value = cleanValue;
}

function appendDigit(digit: string) {
  if (waitingForOperand.value) {
    display.value = digit;
    waitingForOperand.value = false;
  } else {
    if (display.value === "0" && digit !== ".") {
      display.value = digit;
    } else if (digit === "." && display.value.indexOf(".") !== -1) {
      // 防止重复输入小数点
      return;
    } else {
      display.value += digit;
    }
  }
}

function clearDisplay() {
  display.value = "0";
  currentOperator.value = null;
  firstOperand.value = null;
  waitingForOperand.value = false;
}

function toggleSign() {
  if (display.value !== "0") {
    if (display.value.charAt(0) === "-") {
      display.value = display.value.slice(1);
    } else {
      display.value = "-" + display.value;
    }
  }
}

function calculatePercentage() {
  const value = parseFloat(display.value);
  display.value = (value / 100).toString();
}

function setOperator(operator: string) {
  const inputValue = parseFloat(display.value);

  if (firstOperand.value === null) {
    firstOperand.value = inputValue;
  } else if (currentOperator.value) {
    const result = performCalculation();
    if (result !== null) {
      display.value = String(result);
      firstOperand.value = result;
    }
  }

  waitingForOperand.value = true;
  currentOperator.value = operator;
}

function performCalculation(): number | null {
  const inputValue = parseFloat(display.value);

  if (firstOperand.value === null || currentOperator.value === null) {
    return null;
  }

  let result = 0;
  switch (currentOperator.value) {
    case "+":
      result = firstOperand.value + inputValue;
      break;
    case "-":
      result = firstOperand.value - inputValue;
      break;
    case "*":
      result = firstOperand.value * inputValue;
      break;
    case "/":
      if (inputValue === 0) {
        display.value = "Error";
        return null;
      }
      result = firstOperand.value / inputValue;
      break;
    default:
      return null;
  }

  return result;
}

function calculate() {
  const result = performCalculation();

  if (result !== null) {
    display.value = String(result);
    firstOperand.value = result;
  }

  currentOperator.value = null;
  waitingForOperand.value = true;
}

function handleButtonClick(buttonValue: string) {
  switch (buttonValue) {
    case "AC":
      clearDisplay();
      break;
    case "+/-":
      toggleSign();
      break;
    case "%":
      calculatePercentage();
      break;
    case "+":
    case "-":
    case "*":
    case "/":
      setOperator(buttonValue);
      break;
    case "=":
      calculate();
      break;
    case ".":
      if (waitingForOperand.value) {
        display.value = "0.";
        waitingForOperand.value = false;
      } else if (display.value.indexOf(".") === -1) {
        display.value += ".";
      }
      break;
    default: // 数字按钮
      appendDigit(buttonValue);
      break;
  }
}

// 监听显示值变化，确保格式正确
watch(display, (newVal) => {
  if (
    newVal === "" ||
    (isNaN(parseFloat(newVal)) && newVal !== "-" && newVal !== "0")
  ) {
    display.value = "0";
  }
});
</script>

<template>
  <div class="calculator">
    <div class="display-container">
      <el-input
          ref="inputRef"
          v-model="display"
          class="display"
          @input="inputDisplay"
          @keydown.enter="calculate"
          readonly
      />
    </div>

    <div class="buttons-grid">
      <el-button
          v-for="(button, index) in buttons"
          :key="index"
          :type="button.type === 'primary' ? 'primary' : 'default'"
          :class="{
          'button-zero': button.value === '0',
          'operator-button': ['+', '-', '*', '/', '=', 'AC', '±', '%'].includes(button.value)
        }"
          @click="handleButtonClick(button.value)"
      >
        {{ button.label }}
      </el-button>
    </div>
  </div>
</template>

<style scoped>
.calculator {
  width: 320px;
  margin: 0 auto;
  text-align: center;
  font-family: 'Helvetica Neue', Arial, sans-serif;
}

.display-container {
  margin-bottom: 15px;
}

.display {
  font-size: 2rem !important;
  text-align: right !important;
}

:deep(.el-input__wrapper) {
  padding: 20px !important;
  background-color: #f5f5f5 !important;
  box-shadow: 0 0 0 1px #dcdfe6 inset !important;
}

:deep(.el-input__inner) {
  text-align: right !important;
  font-size: 2rem !important;
  color: #666 !important;
  background-color: #f5f5f5 !important;
}

.buttons-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 10px;
}

:deep(.el-button) {
  height: 70px !important;
  font-size: 1.5rem !important;
  border-radius: 8px !important;
  border: none !important;
  margin-left: 0px !important;
  width: 100%;
}

:deep(.el-button.button-zero) {
  grid-column: span 2;
}

:deep(.el-button.operator-button) {
  background-color: #ff9800 !important;
  color: white !important;
  border-color: #ff9800 !important;
}

:deep(.el-button.operator-button:hover) {
  background-color: #f57c00 !important;
  border-color: #f57c00 !important;
}

:deep(.el-button.operator-button:active) {
  background-color: #ef6c00 !important;
  border-color: #ef6c00 !important;
}

:deep(.el-button--danger) {
  background-color: #f44336 !important;
  border-color: #f44336 !important;
  color: white !important;
}

:deep(.el-button--danger:hover) {
  background-color: #d32f2f !important;
  border-color: #d32f2f !important;
}

:deep(.el-button--danger:active) {
  background-color: #c62828 !important;
  border-color: #c62828 !important;
}
</style>
